package es.cazadoresmadridejos.beans.controller.deer;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import es.cazadoresmadridejos.beans.manager.deer.DeerManager;
import es.cazadoresmadridejos.beans.manager.partner.PartnerManager;
import es.cazadoresmadridejos.beans.manager.session.UserPreferences;
import es.cazadoresmadridejos.beans.validator.deer.DeerValidator;
import es.cazadoresmadridejos.model.Deer;
import es.cazadoresmadridejos.objs.datapicker.DeerDataPicker;
import es.cazadoresmadridejos.propertyeditor.DeerPropertyEditor;
import es.cazadoresmadridejos.util.constants.Constants;
import es.cazadoresmadridejos.util.validation.ValidationContainer;

@SessionAttributes({"deerDataPicker","partnersMap"})
@Controller
public class DeerCreateModifyController {

	@Autowired private DeerManager deerManager;
	@Autowired private PartnerManager partnerManager;
	@Autowired private DeerValidator deerValidator;
	@Autowired private MessageSource messageSource;
	@Autowired(required=false) private UserPreferences userPreferences;
	@InitBinder
	public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Throwable{
		binder.registerCustomEditor(Deer.class, new DeerPropertyEditor(deerManager));
		binder.registerCustomEditor(Date.class, "date",new CustomDateEditor(Constants.sdf,true));
	}

	@RequestMapping(value="/deerCreateModify.html",method=RequestMethod.GET)
	public ModelAndView createModify() throws Throwable {
		ModelAndView mv = new ModelAndView();

		List<Deer> deerAssistances = deerManager.findAllAsistances(userPreferences.getReason().getId());

		mv.addObject("deerAssiances",deerAssistances);

		String string = partnerManager.findAllForAutocomplete();
		mv.addObject("partners",string);

		DeerDataPicker dp =new DeerDataPicker();
		dp.setDeerAssistances(deerAssistances);

		mv.addObject("deerDataPicker",dp);

		Set<Long> partnersMap = new HashSet<Long>();

		for (Deer deer : dp.getDeerAssistances()) {
			partnersMap.add(deer.getPartner().getId());
		}
		mv.addObject("partnersMap",partnersMap);
		return mv;
	}
	@RequestMapping(value="/deerCreateModifyAdd.html")
	public ModelAndView createModifyTable(
			@RequestParam(value="partnerId",required=false) Long partnerId,
			@RequestParam(value="payment",required=false) Double payment,
			@RequestParam(value="prePayment",required=false) Double prePayment,
			@RequestParam(value="date",required=false) String date,
			@ModelAttribute("deerDataPicker") DeerDataPicker dp,
			@ModelAttribute("partnersMap") Set<Long> partnersMap) throws Throwable {
		ModelAndView mv = new ModelAndView("deerCreateModifyTable");

		if(!partnersMap.contains(partnerId)){
			Deer deer = new Deer();
			deer.setPartner(partnerManager.get(partnerId));
			if(!StringUtils.isBlank(date)){
				deer.setDate(Constants.sdf.parse(date));
			}
			if(payment != null){
				deer.setPayment(BigDecimal.valueOf(payment));
			}
			if(prePayment != null){
				deer.setPrePayment(BigDecimal.valueOf(prePayment));
			}
			deer.setReason(userPreferences.getReason());

			dp.getDeerAssistances().add(deer);
			partnersMap.add(partnerId);
		}
		mv.addObject("deerAssiances",dp.getDeerAssistances());

		return mv;
	}
	@RequestMapping(value="/deerCreateModifyDelete.html")
	public ModelAndView createModifyTableDelete(
			@RequestParam(value="partnerId") Long partnerId,
			@ModelAttribute("deerDataPicker") DeerDataPicker dp,
			@ModelAttribute("partnersMap") Set<Long> partnersMap) throws Throwable {
		ModelAndView mv = new ModelAndView("deerCreateModifyTable");

		if(partnersMap.contains(partnerId)){
			Iterator<Deer> it = dp.getDeerAssistances().iterator();
			while(it.hasNext()){
				Deer deer = it.next();
				if(deer.getPartner().getId().equals(partnerId)){
					it.remove();
					partnersMap.remove(partnerId);
					break;
				}
			}
		}
		mv.addObject("deerAssiances",dp.getDeerAssistances());

		return mv;
	}

	@RequestMapping(value="/deerCreateModify.html",method=RequestMethod.POST)
	public ModelAndView submit(
			@ModelAttribute("deerDataPicker") DeerDataPicker deerDataPicker, 
			BindingResult result, 
			SessionStatus status,
			HttpServletRequest request
			) throws Throwable {

		ModelAndView mv = new ModelAndView("redirect:index.html");
		mv.addObject("screen","deerList.html");

		List<Deer> list = deerDataPicker.getDeerAssistances();
		List<ValidationContainer> errors = new ArrayList<ValidationContainer>();

		for (Deer deer2 : list) {
			errors.addAll(deerValidator.validate(deer2));
		}

		if(errors.isEmpty()){
			deerManager.saveAll(list,userPreferences.getReason().getId());
			status.setComplete();
			mv.addObject("okMessage", "THE_PROCESS_FINISHED_SUCCESSFULLY");
		}else{
			mv.addObject("errors",errors);
		}

		return mv;
	}
}
